package cn.kow.kmall.service.impl;

import cn.kow.kmall.common.enums.KmallResultEnum;
import cn.kow.kmall.dao.AddressRepository;
import cn.kow.kmall.pojo.dto.AddressDTO;
import cn.kow.kmall.pojo.entity.Address;
import cn.kow.kmall.service.AddressService;
import cn.kow.kmall.core.constant.KmallStatusConstant;
import cn.kow.kmall.core.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service("addressService")
public class AddressServiceImpl implements AddressService {

    @Autowired
    private AddressRepository addressRepository;

    @Override
    public List<Address> list(Long uid) {
        Address exampleAddress = new Address();
        exampleAddress.setStatus(KmallStatusConstant.NORMAL);
        exampleAddress.setUid(uid);
        return addressRepository.findAll(Example.of(exampleAddress), Sort.by(Sort.Direction.DESC, "defaulted", "createTime"));
    }

    @Override
    public Address addOrUpdate(Long uid, AddressDTO addressDTO) {
        Long id = addressDTO.getId();
        String name =  addressDTO.getName();
        String phone = addressDTO.getPhone();
        String province = addressDTO.getProvince();
        String city = addressDTO.getCity();
        String county = addressDTO.getCounty();
        String addressDetail = addressDTO.getAddress();
        Boolean defaulted = addressDTO.getDefaulted();

        List<Address> addressList = new ArrayList<>();
        if (id == null || id == 0) {
            // 地址不能超过20条
            addressList = list(uid);
            if (addressList.size() >= 20) {
                throw new ServiceException(KmallResultEnum.ADDRESS_ADD_LIMIT);
            }
            id = null;
        }

        // 修改的地址为默认地址，将原默认地址更新掉
        if (defaulted) {
            if (null == addressList || addressList.isEmpty()) {
                addressList = list(uid);
            }
            List<Address> defaultAddressList = addressList.stream().filter(address -> address.getDefaulted()).map(address -> {
                address.setDefaulted(false);
                return address;
            }).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(defaultAddressList)) {
                addressRepository.saveAll(defaultAddressList);
            }
        }

        Address address;
        if (id == null || id == 0) {
            address = new Address();
            address.setUid(uid);
            address.setCreateTime(new Date());
            address.setStatus(KmallStatusConstant.NORMAL);
        } else {
            address = get(uid, id);
        }
        address.setName(name);
        address.setPhone(phone);
        address.setProvince(province);
        address.setCity(city);
        address.setCounty(county);
        address.setAddress(addressDetail);
        address.setDefaulted(defaulted);
        return addressRepository.saveAndFlush(address);
    }

    @Override
    public Address get(Long uid, Long addressId) {
        Address exampleAddress = new Address();
        exampleAddress.setStatus(KmallStatusConstant.NORMAL);
        exampleAddress.setUid(uid);
        exampleAddress.setId(addressId);
        return addressRepository.findOne(Example.of(exampleAddress)).orElseThrow(() -> new ServiceException(KmallResultEnum.ADDRESS_NOT_FOUND));
    }

    @Override
    public void delete(Long id) {
        addressRepository.deleteById(id);
    }

    @Override
    public Address getDefualt(Long uid) {
        List<Address> addressList = list(uid);
        if (!CollectionUtils.isEmpty(addressList)) {
            for(Address address : addressList) {
                if (address.getDefaulted()) {
                    return address;
                }
            }
            return addressList.get(0);
        }
        return null;
    }

}
